/**
 * @description: 灯光处理
 * @file: light.ts
 * @author: Evan
 * @date: 2025.07.17 14:58:40
 * @week: 周四
 * @version: V
 */

import { Scene } from '../class'
import * as MD from '../data/methods'

const { THREE } = MD

type ST = InstanceType<typeof Scene>

export function light(core: ST) {
  const params = {
    intensity: 1,
    color: 0xffffff,
    castShadow: false,
    distance: 10,
    penumbra: 1,
    decay: 1
  }
  return {
    add() {
      const gui = core.gui
      if (!core.container) return
      const group = gui.addFolder('灯光')

      // 环境光
      const ambientLight = core.scene.getObjectByProperty(
        'isAmbientLight',
        true
      ) as MD.THREE.AmbientLight
      if (ambientLight) {
        group.add(ambientLight, 'intensity', 0, 10).name('环境光强度')
        group.addColor(ambientLight, 'color').name('环境光颜色')
      }

      const option = {
        bgCode: '',
        hdr: '',
        color1: 0xffffff,
        color2: 0xffffff
      }
      // 平行光
      const directionalLights = core.scene.getObjectsByProperty(
        'isDirectionalLight',
        true
      ) as MD.THREE.DirectionalLight[]

      if (directionalLights.length) {
        const [dirLight1, dirLight2] = directionalLights

        const dirLightHelper1 = new THREE.DirectionalLightHelper(dirLight1, 1, dirLight1.color)
        dirLightHelper1.visible = false
        core.addObject(dirLightHelper1)
        option.color1 = dirLight1.color.getHex()
        group
          .addColor(option, 'color1')
          .name('平行光颜色')
          .onChange(e => {
            dirLight1.color.set(e)
            dirLightHelper1.traverse((el: any) => {
              if (el.color) {
                el.color.set(e)
              } else if (el.isLine) {
                el.material.color.set(e)
              }
            })
          })
        group.add(dirLight1, 'intensity', 0, 10).name('平行光强度')
        group.add(dirLight1.position, 'y', 500, 100000).name('平行光高度')
        group.add(dirLightHelper1, 'visible').name('平行光辅助')

        if (dirLight2) {
          group.add(dirLight2, 'visible').name('平行光2')

          option.color2 = dirLight2.color.getHex()
          const dirLightHelper2 = new THREE.DirectionalLightHelper(dirLight2, 1, dirLight2.color)
          dirLightHelper2.visible = false
          core.addObject(dirLightHelper2)
          option.color1 = dirLight2.color.getHex()
          group
            .addColor(option, 'color1')
            .name('平行光颜色')
            .onChange(e => {
              dirLight2.color.set(e)
              dirLightHelper2.traverse((el: any) => {
                if (el.color) {
                  el.color.set(e)
                } else if (el.isLine) {
                  el.material.color.set(e)
                }
              })
            })
          group.add(dirLight2, 'intensity', 0, 10).name('平行光2强度')
          group.add(dirLight2.position, 'y', 500, 100000).name('平行光高度2')
          group.add(dirLightHelper2, 'visible').name('平行光2辅助')
        }
      }

      group
        .add(params, 'intensity', 1, 20)
        .name('聚光灯强度')
        .onChange(() => {
          this.spotLight()
        })
      group
        .addColor(params, 'color')
        .name('聚光灯颜色')
        .onChange(() => {
          this.spotLight()
        })
      group
        .add(params, 'castShadow')
        .name('聚光灯阴影')
        .onChange(() => {
          this.spotLight()
        })
      group
        .add(params, 'distance', 0.1, 1000)
        .name('聚光灯光照距离')
        .onChange(() => {
          this.spotLight()
        })
      group
        .add(params, 'penumbra', 0, 1)
        .name('聚光灯半影衰减')
        .onChange(() => {
          this.spotLight()
        })
      group
        .add(params, 'decay', 0, 1)
        .name('聚光灯光照衰减')
        .onChange(() => {
          this.spotLight()
        })
      group.close()
    },

    // 聚光灯
    spotLight() {
      core.modelGroup?.traverse((el: any) => {
        if (el.isSpotLight) {
          el.intensity = params.intensity
          el.castShadow = params.castShadow
          el.distance = params.distance
          el.penumbra = params.penumbra
          el.decay = params.decay
          el.color.set(params.color)
        }
      })
      core.helperGroup?.traverse((el: any) => {
        if (el.type === 'SpotLightHelper') {
          el.children[0].material.color.set(params.color)
        }
      })
    }
  }
}
